Underneath all the hype and trappings, AJAX is just a means of loading data from the server to the web browser, or client,
without a visible page refresh. This data can take many forms, and we
have many options for what to do with it when it arrives. We'll see this
by performing the same basic task in many ways.
We are going to build a page
that displays entries from a dictionary, grouped by the starting letter
of the dictionary entry. The HTML defining the content area of the page
will look like this:
<div id="dictionary">
</div>
Yes, really! Our page will have no content to begin with. We are going to use jQuery's various AJAX methods to populate this<div> with dictionary entries.
We're going to need a way to trigger the loading process, so we'll add some links for our event handlers to latch onto:
<div class="letters">
<div class="letter" id="letter-a">
<h3><a href="#">A</a></h3>
</div>
<div class="letter" id="letter-b">
<h3><a href="#">B</a></h3>
</div>
<div class="letter" id="letter-c">
<h3><a href="#">C</a></h3>
</div>
<div class="letter" id="letter-d">
<h3><a href="#">D</a></h3>
</div>
</div>
As always, a real-world implementation should use progressive enhancement
to make the page function without requiring JavaScript. Here, to
simplify our example, the links do nothing until we add behaviors to
them with jQuery.
Adding a few CSS rules, we get a page that looks like this:
Now we can focus on getting content onto the page.
Appending HTML
AJAX applications are often no more than a request for a chunk of HTML. This technique, sometimes referred to as AHAH (Asynchronous HTTP and HTML), is almost trivial to implement with jQuery. First we need some HTML to insert, which we'll place in a file called a.html alongside our main document. This secondary HTML file begins:
<div class="entry">
data, AJAXHTML, appending<h3 class="term">ABDICATION</h3>
<div class="part">n.</div>
<div class="definition">
An act whereby a sovereign attests his sense of the high
temperature of the throne.
<div class="quote">
<div class="quote-line">Poor Isabella's Dead, whose
abdication</div>
<div class="quote-line">Set all tongues wagging in the
Spanish nation.</div>
<div class="quote-line">For that performance 'twere
unfair to scold her:</div>
<div class="quote-line">She wisely left a throne too
hot to hold her.</div>
<div class="quote-line">To History she'll be no royal
riddle —</div>
<div class="quote-line">Merely a plain parched pea that
jumped the griddle.</div>
<div class="quote-author">G.J.</div>
</div>
</div>
</div>
<div class="entry">
<h3 class="term">ABSOLUTE</h3>
<div class="part">adj.</div>
<div class="definition">
Independent, irresponsible. An absolute monarchy is one
in which the sovereign does as he pleases so long as he
pleases the assassins. Not many absolute monarchies are
left, most of them having been replaced by limited
monarchies, where the sovereign's power for evil (and for
good) is greatly curtailed, and by republics, which are
governed by chance.
</div>
</div>
The page continues with more entries in this HTML structure. Rendered on its own, this page is quite plain:
Note that a.html is not a true HTML document; it contains no<html>, <head>, or<body>, all of which are normally required. We usually call such a file a snippet or fragment; its only purpose is to be inserted into another HTML document, which we'll accomplish now:
$(document).ready(function() {
$('#letter-a a').click(function() {
$('#dictionary').load('a.html');
return false;
});
});
The .load()
method does all our heavy lifting for us! We specify the target location
for the HTML snippet by using a normal jQuery selector, and then pass
the URL of the file to be loaded as a parameter to the method. Now, when
the first link is clicked, the file is loaded and placed inside<div id="dictionary">. The browser will render the new HTML as soon as it is inserted:
Note that the HTML is now
styled, whereas before it was plain. This is due to the CSS rules in the
main document; as soon as the new HTML snippet is inserted, the rules
apply to its tags as well.
When testing this
example, the dictionary definitions will probably appear instantaneously
when the button is clicked. This is a hazard of working on our
applications locally; it is hard to account for delays in transferring
documents across the network. Suppose we added an alert box to display
after the definitions are loaded:
$(document).ready(function() {
$('#letter-a a').click(function() {
$('#dictionary').load('a.html');
alert('Loaded!');
return false;
});
});
We might assume from the
structure of this code that the alert can only be displayed after the
load has been performed. JavaScript execution is usually synchronous, working on one task after another in strict sequence.
However, when this particular
code is tested on a production web server, the alert will quite possibly
have come and gone before the load has completed, due to network lag.
This happens because all AJAX calls are by default asynchronous.
Otherwise, we'd have to call it SJAX, which hardly has the same ring to
it! Asynchronous loading means that once the HTTP request to retrieve
the HTML snippet is issued, script execution immediately resumes without
waiting. Some time later, the browser receives the response from the
server and handles it. This is generally desired behavior; it is
unfriendly to lock up the whole web browser while waiting for data to be
retrieved.
If actions must be delayed until the load has been completed, jQuery provides a callback for this. An example will be provided below.